#! -*- coding: utf-8 -*-
"""
@Info: 分类API接口
"""
import json
import time
import logging
import tornado.ioloop
from tornado.httpserver import HTTPServer
from logging.handlers import RotatingFileHandler
from inference import Inference
import requests
import arguments as args
import traceback
from date_standard import date_standard

WEB_PORT = 8893

predictor1 = Inference(args.OPERATE_MODEL_CONFIG)
print('模型加载成功.....')

# 日志记录器，记录web请求和回调细节，便于调试排错
file_handler = RotatingFileHandler(
    'log/classify.log', maxBytes=20 * 1024 * 1024, backupCount=30)
file_handler.setFormatter(logging.Formatter(
    '%(asctime)s %(levelname)s %(message)s'))
logger = logging.getLogger('classify')
logger.setLevel(logging.INFO)
logger.addHandler(file_handler)

itemMapping = {
    '任务编号': 'taskCode',
    '工作站名称': 'workstationName',
    '订单编号': 'workorderCode',  # 订单编号
    '工作站编号': 'workstationCode',
    '工序编号': 'processCode',
    '物料编号': 'itemCode',
    '班组编号': 'teamCode',
    '状态': 'status',
    '排程时间': 'startTime',  # 开始时间
    '结束时间': 'endTime',
    '合同交付时间': 'deliveryTime',
    '任务开始时间': 'realStartTime',
    '任务结束时间': 'realEndTime',
    '优先级': 'productionPriority',
    '产品': 'productName',
    'TASK状态': 'taskStatus',
    'MO状态': 'moStatus',  # workOrderStatus
    'TSK排程开始时间': 'taskStartTime',
    'TSK排程结束时间': 'taskEndTime',
    'TSK实际开始时间': 'taskActualStartTime',  # TSK实际开始时间
    'TSK实际结束时间': 'taskActualEndTime',  # TSK实际结束时间
    'TSK延期时间': 'taskExtensionTime',
    'SO交付时间': 'salesOrdersDeliveryTime',
    'MO重排前预计交付时间': 'moEstimatedBeforeDeliveryTime',
    'MO重排后预计交付时间': 'moEstimatedAfterDeliveryTime',
    'MO重排差异': 'moRearrangementDifference',  # MO重排差异
    'MO延期时间': 'moExtensionTime'  # MO延期时间
}

taskStatusMapping = {
    '已排产': 'PLANNED',
    '已排': 'PLANNED',
    '已锁定': 'LOCKED',
    '锁定': 'LOCKED',
    '已下发': 'PUBLISHED',
    '生产中': 'INPRODUCTION',
    '已完成': 'COMPLETED'
}

workOrderStatusMapping = {  # moStatus
    '待排产': 'TOPLAN',
    '待排': 'TOPLAN',
    '已排产': 'PLANNED',
    '已排': 'PLANNED',
    '已锁定': 'LOCKED',
    '锁定': 'LOCKED',
    '已下发': 'PUBLISHED',
    '生产中': 'INPRODUCTION',
    '已完成': 'COMPLETED'
}

intentIdMapping = {
    ('查询', '任务编号'): 1,
    ('查询', '工作站名称'): 2,
    ('查询', '订单编号'): 3,
    ('查询', '产品'): 4,
    ('查询', '优先级'): 5,
    ('查询', 'SO交付时间'): 6,
    # ('重排', '工作站名称'): 7,
    ('插单', '订单编号'): 9,
    ('查询', 'TASK状态'): 11,
    ('查询', 'MO状态'): 12,
    ('查询', 'TSK排程开始时间'): 13,
    ('查询', 'TSK排程结束时间'): 14,
    ('查询', 'TSK实际开始时间'): 15,
    ('查询', 'TSK实际结束时间'): 16,
    ('查询', 'TSK延期时间'): 17,
    ('查询', 'MO重排前预计交付时间'): 19,
    ('查询', 'MO重排后预计交付时间'): 20,
    ('查询', 'MO重排差异'): 21,
    ('查询', 'MO延期时间'): 22
}

answerMapping = {
    0: '您好，我是AIPS，专注于生产排产相关操作的人工智能大模型。请问您有相关指令需要操作吗？谢谢。',
    1: '已根据您的要求完成查询，请预览。',
    2: '已根据您的要求完成查询，请预览。',
    3: '已根据您的要求完成查询，请预览。',
    4: '已根据您的要求完成查询，请预览。',
    5: '已根据您的要求完成查询，请预览。',
    6: '已根据您的要求完成查询，请预览。',
    9: '好的，马上执行。',  # 执行结束：已根据您的要求完成重排，请预览。确认无误后点击发布，或取消重排。
    11: '已根据您的要求完成查询，请预览。',
    12: '已根据您的要求完成查询，请预览。',
    13: '已根据您的要求完成查询，请预览。',
    14: '已根据您的要求完成查询，请预览。',
    15: '已根据您的要求完成查询，请预览。',
    16: '已根据您的要求完成查询，请预览。',
    17: '已根据您的要求完成查询，请预览。',
    19: '已根据您的要求完成查询，请预览。',
    20: '已根据您的要求完成查询，请预览。',
    21: '已根据您的要求完成查询，请预览。',
    22: '已根据您的要求完成查询，请预览。',
}


class MainHandler(tornado.web.RequestHandler):

    def data_received(self, chunk):
        pass

    def post(self, *args, **kwargs):
        try:
            request_json = json.loads(self.request.body)
            query = request_json.get('query', '')
            logger.info('#' * 50)
            logger.info(f'query: {query}')
            # second_business_list = predictor2.predict(sentence)
            # second_business = second_business_list[0]
            time_start = time.time()
            operate_type_list = predictor1.predict(query)
            time_end = time.time()
            print('耗时：{}ms,operate_type_list{}'.format(int((time_end-time_start)*1000),operate_type_list))
            operate_type = operate_type_list[0]
            print(f'operate_type: {operate_type}')
            api = 'http://127.0.0.1:8892/ner'
            params = {
                'query': query,
                'operate_type': operate_type['label']
            }
            keywords = {}
            score = operate_type['score']
            if (str(operate_type['label']) != '0') & (score > 0.15):
                response = requests.post(api, json=params).json()
                logger.info(f'NER response: {response}')
                for entity in response['entities']:
                    # if entity[2] == 'TSK排程结束时间':
                    #     entity[2] = '任务编号'
                    # 格式化时间
                    if entity[2] == 'TASK状态':
                        entity[3] = taskStatusMapping[entity[3]]
                    if entity[2] == 'MO状态':
                        entity[3] = workOrderStatusMapping[entity[3]]
                    if ('时间' in entity[2]) and (entity[2] != 'MO延期时间') and (entity[2] != 'TSK延期时间'):
                        left, right = date_standard(entity[3])
                        base = itemMapping[entity[2]]
                        keywords[base + 'Left'] = left
                        keywords[base + 'Reft'] = right
                    else:
                        keywords[itemMapping[entity[2]]] = entity[3]

                # intentId = intentIdMapping[(operate_type['label'], response['entities'][0][2])]
                intentId = int(operate_type['label'])
            result = {
                'code': 200,
                'msg': 'success',
                'data': {
                    'answer': answerMapping[intentId],
                    'intentId': intentId,
                    'keywords': keywords
                }
            }
            logger.info(f'response: {result}')
            self.write(result)
        except Exception as e:
            print(traceback.format_exc())
            logger.error(traceback.format_exc())
            self.write({
                'code': 400,
                'msg': e,
                'data': {}
            })


application = tornado.web.Application([
    ("/classify", MainHandler)
])

if __name__ == '__main__':
    server = HTTPServer(application)
    server.bind(WEB_PORT)
    server.start(num_processes=1)  # redis_info.num_processes)
    print("server is running on {}".format(WEB_PORT))
    tornado.ioloop.IOLoop.current().start()
